using System;
using Server;
using Server.Mobiles;
using Server.Items;

namespace Server.Engines.Quests.Haven
{
	public enum CannonDirection
	{
		North,
		East,
		South,
		West
	}

	public class Cannon : BaseAddon
	{
		private CannonDirection m_CannonDirection;
		private MilitiaCanoneer m_Canoneer;

		[CommandProperty( AccessLevel.GameMaster )]
		public CannonDirection CannonDirection { get { return m_CannonDirection; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public MilitiaCanoneer Canoneer { get { return m_Canoneer; } set { m_Canoneer = value; } }

		[Constructable]
		public Cannon( CannonDirection direction )
		{
			m_CannonDirection = direction;

			switch ( direction )
			{
				case CannonDirection.North:
				{
					AddComponent( new CannonComponent( 0xE8D ), 0, 0, 0 );
					AddComponent( new CannonComponent( 0xE8C ), 0, 1, 0 );
					AddComponent( new CannonComponent( 0xE8B ), 0, 2, 0 );

					break;
				}
				case CannonDirection.East:
				{
					AddComponent( new CannonComponent( 0xE96 ), 0, 0, 0 );
					AddComponent( new CannonComponent( 0xE95 ), -1, 0, 0 );
					AddComponent( new CannonComponent( 0xE94 ), -2, 0, 0 );

					break;
				}
				case CannonDirection.South:
				{
					AddComponent( new CannonComponent( 0xE91 ), 0, 0, 0 );
					AddComponent( new CannonComponent( 0xE92 ), 0, -1, 0 );
					AddComponent( new CannonComponent( 0xE93 ), 0, -2, 0 );

					break;
				}
				default:
				{
					AddComponent( new CannonComponent( 0xE8E ), 0, 0, 0 );
					AddComponent( new CannonComponent( 0xE8F ), 1, 0, 0 );
					AddComponent( new CannonComponent( 0xE90 ), 2, 0, 0 );

					break;
				}
			}
		}

		public Cannon( Serial serial ) : base( serial )
		{
		}

		public void DoFireEffect( IPoint3D target )
		{
			Point3D from;
			switch ( m_CannonDirection )
			{
				case CannonDirection.North:	from = new Point3D( X, Y - 1, Z ); break;
				case CannonDirection.East:	from = new Point3D( X + 1, Y, Z ); break;
				case CannonDirection.South:	from = new Point3D( X, Y + 1, Z ); break;
				default:					from = new Point3D( X - 1, Y, Z ); break;
			}

			Effects.SendLocationEffect( from, Map, 0x36B0, 16, 1 );
			Effects.PlaySound( from, Map, 0x11D );

			Effects.SendLocationEffect( target, Map, 0x36B0, 16, 1 );
			Effects.PlaySound( target, Map, 0x11D );
		}

		public void Fire( Mobile from, Mobile target )
		{
			DoFireEffect( target );

			target.Damage( 9999, from );
		}

		public override bool HandlesOnMovement { get { return m_Canoneer != null && !m_Canoneer.Deleted && m_Canoneer.Active; } }

		public override void OnMovement( Mobile m, Point3D oldLocation )
		{
			if ( m_Canoneer == null || m_Canoneer.Deleted || !m_Canoneer.Active )
				return;

			bool canFire;
			switch ( m_CannonDirection )
			{
				case CannonDirection.North:
					canFire = m.X >= X - 7 && m.X <= X + 7 && m.Y == Y - 7 && oldLocation.Y < Y - 7;
					break;
				case CannonDirection.East:
					canFire = m.Y >= Y - 7 && m.Y <= Y + 7 && m.X == X + 7 && oldLocation.X > X + 7;
					break;
				case CannonDirection.South:
					canFire = m.X >= X - 7 && m.X <= X + 7 && m.Y == Y + 7 && oldLocation.Y > Y + 7;
					break;
				default:
					canFire = m.Y >= Y - 7 && m.Y <= Y + 7 && m.X == X - 7 && oldLocation.X < X - 7;
					break;
			}

			if ( canFire && m_Canoneer.WillFire( this, m ) )
				Fire( m_Canoneer, m );
		}

		public override void Serialize( GenericWriter writer )
		{
			if ( m_Canoneer != null && m_Canoneer.Deleted )
				m_Canoneer = null;

			base.Serialize( writer );

			writer.Write( (int) 0 ); // version

			writer.WriteEncodedInt( (int) m_CannonDirection );
			writer.Write( (Mobile) m_Canoneer );
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );

			int version = reader.ReadInt();

			m_CannonDirection = (CannonDirection) reader.ReadEncodedInt();
			m_Canoneer = (MilitiaCanoneer) reader.ReadMobile();
		}
	}

	public class CannonComponent : AddonComponent
	{
		[CommandProperty( AccessLevel.GameMaster )]
		public MilitiaCanoneer Canoneer
		{
			get { return Addon is Cannon ? ((Cannon)Addon).Canoneer : null; }
			set { if ( Addon is Cannon ) ((Cannon)Addon).Canoneer = value; }
		}

		public CannonComponent( int itemID ) : base( itemID )
		{
		}

		public CannonComponent( Serial serial ) : base( serial )
		{
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

			writer.Write( (int) 0 ); // version
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );

			int version = reader.ReadInt();
		}
	}
}